home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -in_the_mag- / workbench / adf / adflib / adflib.lha / Lib / adf_raw.c < prev    next >
C/C++ Source or Header  |  1999-05-25  |  7KB  |  298 lines

  1. /*
  2.  *  ADF Library. (C) 1997-1998 Laurent Clevy
  3.  *
  4.  *  adf_raw.c
  5.  *
  6.  * logical disk/volume code
  7.  */
  8.  
  9. #include <limits.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #include "adf_str.h"
  14. #include "adf_raw.h"
  15. #include "adf_blk.h"
  16. #include "adf_disk.h"
  17. #include "adf_util.h"
  18. #include "adf_err.h"
  19. #include "defendian.h"
  20.  
  21. extern struct Env adfEnv;
  22.  
  23. int swapTable[MAX_SWTYPE+1][15]={
  24.     { 4, SW_CHAR, 2, SW_LONG, 1012, SW_CHAR, 0, 1024 },     /* first bytes of boot */
  25.     { 108, SW_LONG, 40, SW_CHAR, 10, SW_LONG, 0, 512 },        /* root */
  26.     { 6, SW_LONG, 488, SW_CHAR, 0, 512 },                      /* data */
  27.                                                             /* file, dir, entry */
  28.     { 82, SW_LONG, 92, SW_CHAR, 3, SW_LONG, 36, SW_CHAR, 11, SW_LONG, 0, 512 },
  29.     { 6, SW_LONG, 0, 24 },                                       /* cache */
  30.     { 128, SW_LONG, 0, 512 },                                /* bitmap, fext */
  31.                                                             /* link */                                        
  32.     { 6, SW_LONG, 64, SW_CHAR, 86, SW_LONG, 32, SW_CHAR, 12, SW_LONG, 0, 512 },
  33.     { 4, SW_CHAR, 39, SW_LONG, 56, SW_CHAR, 10, SW_LONG, 0, 256 }, /* RDSK */
  34.     { 4, SW_CHAR, 127, SW_LONG, 0, 512 },                          /* BADB */
  35.     { 4, SW_CHAR, 8, SW_LONG, 32, SW_CHAR, 31, SW_LONG, 4, SW_CHAR,
  36.       15, SW_LONG, 0, 256 },                                     /* PART */
  37.     { 4, SW_CHAR, 7, SW_LONG, 4, SW_CHAR, 55, SW_LONG, 0, 256 }, /* FSHD */
  38.     { 4, SW_CHAR, 4, SW_LONG, 492, SW_CHAR, 0, 512 }             /* LSEG */
  39.     };
  40.  
  41.  
  42. /*
  43.  * swapEndian
  44.  *
  45.  * magic :-) endian swap function (big -> little for read, little to big for write)
  46.  */
  47.  
  48.     void
  49. swapEndian( unsigned char *buf, int type )
  50. {
  51.     int i,j;
  52.     int p;
  53.  
  54.     i=0;
  55.     p=0;
  56.  
  57.     if (type>MAX_SWTYPE || type<0)
  58.         adfEnv.eFct("SwapEndian: type do not exist");
  59.  
  60.     while( swapTable[type][i]!=0 ) {
  61.         for(j=0; j<swapTable[type][i]; j++) {
  62.             switch( swapTable[type][i+1] ) {
  63.             case SW_LONG:
  64.                 *(unsigned long*)(buf+p)=Long(buf+p);
  65.                 p+=4;
  66.                 break;
  67.             case SW_SHORT:
  68.                 *(unsigned short*)(buf+p)=Short(buf+p);
  69.                 p+=2;
  70.                 break;
  71.             case SW_CHAR:
  72.                 p++;
  73.                 break;
  74.             default:
  75.                 ;
  76.             }
  77.         }
  78.     i+=2;
  79.     }
  80.     if (p!=swapTable[type][i+1]) 
  81.         (*adfEnv.wFct)("Warning: Endian Swapping length\n");
  82.     
  83.  
  84. }
  85.  
  86.  
  87.  
  88.  
  89.  
  90. /*
  91.  * adfReadRootBlock
  92.  *
  93.  * ENDIAN DEPENDENT
  94.  */
  95. RETCODE
  96. adfReadRootBlock(struct Volume* vol, long nSect, struct bRootBlock* root)
  97. {
  98.     unsigned char buf[LOGICAL_BLOCK_SIZE];
  99.  
  100.     if (adfReadBlock(vol, nSect, buf)!=RC_OK)
  101.         return RC_ERROR;
  102.  
  103.     memcpy(root, buf, LOGICAL_BLOCK_SIZE);
  104. #ifdef LITT_ENDIAN
  105.     swapEndian((unsigned char*)root, SWBL_ROOT);    
  106. #endif
  107.  
  108.     if (root->type!=T_HEADER || root->secType!=ST_ROOT) {
  109.         (*adfEnv.wFct)("adfReadRootBlock : id not found");
  110.         return RC_ERROR;
  111.     }
  112.     if (root->checkSum!=adfNormalSum(buf, 20, LOGICAL_BLOCK_SIZE)) {
  113.         (*adfEnv.wFct)("adfReadRootBlock : invalid checksum");
  114.         return RC_ERROR;
  115.     }
  116.         
  117.     return RC_OK;
  118. }
  119.  
  120.  
  121. /*
  122.  * adfWriteRootBlock
  123.  *
  124.  * 
  125.  */
  126. RETCODE adfWriteRootBlock(struct Volume* vol, long nSect, struct bRootBlock* root)
  127. {
  128.     unsigned char buf[LOGICAL_BLOCK_SIZE];
  129.     unsigned long newSum;
  130.  
  131.  
  132.     root->type = T_HEADER;
  133.     root->headerKey = 0L;
  134.     root->highSeq = 0L;
  135.     root->hashTableSize = HT_SIZE;
  136.     root->firstData = 0L;
  137.     /* checkSum, hashTable */
  138.     /* bmflag */
  139.     /* bmPages, bmExt */
  140.     root->nextSameHash = 0L;
  141.     root->parent = 0L;
  142.     root->secType = ST_ROOT;
  143.  
  144.     memcpy(buf, root, LOGICAL_BLOCK_SIZE);
  145. #ifdef LITT_ENDIAN
  146.     swapEndian(buf, SWBL_ROOT);
  147. #endif
  148.  
  149.     newSum = adfNormalSum(buf,20,LOGICAL_BLOCK_SIZE);
  150.     swLong(buf+20, newSum);
  151. //    *(unsigned long*)(buf+20) = swapLong((unsigned char*)&newSum);
  152.  
  153. //     dumpBlock(buf);
  154.     if (adfWriteBlock(vol, nSect, buf)!=RC_OK)
  155.         return RC_ERROR;
  156. //printf("adfWriteRootBlock %ld\n",nSect);
  157.     return RC_OK;
  158. }
  159.  
  160.  
  161. /*
  162.  * adfReadBootBlock
  163.  *
  164.  * ENDIAN DEPENDENT
  165.  */
  166. RETCODE
  167. adfReadBootBlock(struct Volume* vol, struct bBootBlock* boot)
  168. {
  169.     unsigned char buf[1024];
  170.     
  171. //puts("22");
  172.     if (adfReadBlock(vol, 0, buf)!=RC_OK)
  173.         return RC_ERROR;
  174. //puts("11");
  175.     if (adfReadBlock(vol, 1, buf+LOGICAL_BLOCK_SIZE)!=RC_OK)
  176.         return RC_ERROR;
  177.  
  178.     memcpy(boot, buf, LOGICAL_BLOCK_SIZE*2);
  179. #ifdef LITT_ENDIAN
  180.     swapEndian((unsigned char*)boot,SWBL_BOOT);
  181. #endif
  182.     if ( strncmp("DOS",boot->dosType,3)!=0 ) {
  183.         (*adfEnv.wFct)("adfReadBootBlock : DOS id not found");
  184.         return RC_ERROR;
  185.     }
  186. //printf("compsum=%x sum=%x\n",    adfBootSum(buf),boot->checkSum );
  187.  
  188.     if ( boot->data[0]!=0 && adfBootSum(buf)!=boot->checkSum ) {
  189.         (*adfEnv.wFct)("adfReadBootBlock : incorrect checksum"); 
  190.     }
  191.  
  192.     return RC_OK;
  193. }
  194.  
  195. /*
  196.  * adfWriteBootBlock
  197.  *
  198.  *
  199.  *     write bootcode ?
  200.  */
  201. RETCODE
  202. adfWriteBootBlock(struct Volume* vol, struct bBootBlock* boot)
  203. {
  204.     unsigned char buf[LOGICAL_BLOCK_SIZE*2];
  205.     unsigned long newSum;
  206.  
  207.     boot->dosType[0] = 'D';
  208.     boot->dosType[1] = 'O';
  209.     boot->dosType[2] = 'S';
  210.     memcpy(buf, boot, LOGICAL_BLOCK_SIZE*2);
  211. #ifdef LITT_ENDIAN
  212.     swapEndian(buf, SWBL_BOOT);
  213. #endif
  214.  
  215.     if (boot->rootBlock==880 || boot->data[0]!=0) {
  216.         newSum = adfBootSum(buf);
  217.         swLong(buf+4,newSum);
  218. //        *(unsigned long*)(buf+4) = swapLong((unsigned char*)&newSum);
  219.     }
  220.  
  221. /*    dumpBlock(buf);
  222.     dumpBlock(buf+512);
  223. */    
  224.     if (adfWriteBlock(vol, 0, buf)!=RC_OK)
  225.         return RC_ERROR;
  226.     if (adfWriteBlock(vol, 1,  buf+512)!=RC_OK)
  227.         return RC_ERROR;
  228. //puts("adfWriteBootBlock");
  229.     return RC_OK;
  230. }
  231.  
  232.  
  233. /*
  234.  * NormalSum
  235.  *
  236.  * buf = where the block is stored
  237.  * offset = checksum place (in bytes)
  238.  * bufLen = buffer length (in bytes)
  239.  */
  240.     unsigned long
  241. adfNormalSum( UCHAR* buf, int offset, int bufLen )
  242. {
  243.     long newsum;
  244.     int i;
  245.  
  246.     newsum=0L;
  247.     for(i=0; i < (bufLen/4); i++)
  248.         if ( i != (offset/4) )       /* old chksum */
  249.             newsum+=Long(buf+i*4);
  250.     newsum=(-newsum);    /* WARNING */
  251.  
  252.     return(newsum);
  253. }
  254.  
  255. /*
  256.  * adfBitmapSum
  257.  *
  258.  */
  259.     unsigned long 
  260. adfBitmapSum(unsigned char *buf)
  261. {
  262.     unsigned long newSum;
  263.     int i;
  264.     
  265.     newSum = 0L;
  266.     for(i=1; i<128; i++)
  267.         newSum-=Long(buf+i*4);
  268.     return(newSum);
  269. }
  270.  
  271.  
  272. /*
  273.  * adfBootSum
  274.  *
  275.  */
  276.     unsigned long 
  277. adfBootSum(unsigned char *buf)
  278. {
  279.     unsigned long d, newSum;
  280.     int i;
  281.     
  282.     newSum=0L;
  283.     for(i=0; i<256; i++) {
  284.         if (i!=1) {
  285.             d = Long(buf+i*4);
  286.             if ( (ULONG_MAX-newSum)<d )
  287.                 newSum++;
  288.             newSum+=d;
  289.         }
  290.     }
  291.     newSum = ~newSum;    /* not */
  292.  
  293.     return(newSum);
  294. }
  295.  
  296.  
  297. /*#######################################################################################*/
  298.